package com.lemon.exam.common.converter;

import com.lemon.exam.common.entity.view.ViewUserRoleMenuResource;
import io.r2dbc.spi.Row;
import io.r2dbc.spi.RowMetadata;
import org.apache.commons.lang3.tuple.Triple;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.convert.ReadingConverter;
import org.springframework.lang.NonNull;

import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;

/**
 * 视图 view_user_role_menu_resource 转换器
 *
 * @author Lemon
 * @since 2025/4/6 15:27
 */
@ReadingConverter
public class UserRoleMenuResourceConverter implements Converter<Row, ViewUserRoleMenuResource> {
    /**
     * 映射关系
     * 字段 -> 字段类型 -> 字段赋值方法
     */
    private static final Function<ViewUserRoleMenuResource, List<Triple<String, Class<?>, Consumer<Object>>>> MAPPING = entity -> List.of(
            Triple.of("role_id", Long.class, v -> entity.setRoleId((Long) v)),
            Triple.of("role_name", String.class, v -> entity.setRoleName((String) v)),
            Triple.of("role_key", String.class, v -> entity.setRoleKey((String) v)),
            Triple.of("role_status", Integer.class, v -> entity.setRoleStatus((Integer) v)),
            Triple.of("role_deleted", Integer.class, v -> entity.setRoleDeleted((Integer) v)),
            Triple.of("menu_id", Long.class, v -> entity.setMenuId((Long) v)),
            Triple.of("menu_name", String.class, v -> entity.setMenuName((String) v)),
            Triple.of("menu_path", String.class, v -> entity.setMenuPath((String) v)),
            Triple.of("menu_status", Integer.class, v -> entity.setMenuStatus((Integer) v)),
            Triple.of("resource_path", String.class, v -> entity.setResourcePath((String) v))
    );

    @Override
    @NonNull
    public ViewUserRoleMenuResource convert(Row source) {
        RowMetadata meta = source.getMetadata();
        ViewUserRoleMenuResource entity = new ViewUserRoleMenuResource();
        MAPPING.apply(entity).forEach(mapping -> {
            if (meta.contains(mapping.getLeft())) {
                mapping.getRight().accept(source.get(mapping.getLeft(), mapping.getMiddle()));
            }
        });
        return entity;
    }
}
